/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package it.nyquistmeteocal.beans;

import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import it.nyquistmeteocal.entity.Event;
import it.nyquistmeteocal.boundary.EventManager;
import it.nyquistmeteocal.entity.Notification;
import it.nyquistmeteocal.boundary.NotificationManager;
import it.nyquistmeteocal.boundary.UserManager;
import it.nyquistmeteocal.entity.UserNotification;
import it.nyquistmeteocal.boundary.UserNotificationManager;
import it.nyquistmeteocal.control.Weatherchecker;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import javax.ejb.EJB;
import javax.enterprise.context.RequestScoped;
import javax.inject.Named;

/**
 *
 * @author gatb27
 */
@Named
@RequestScoped
public class WeatherBean {

    @EJB
    private EventManager em;
    @EJB
    private NotificationManager nm;
    @EJB
    private UserNotificationManager unm;
    @EJB
    private UserManager um;

    private Weatherchecker wc = new Weatherchecker();

    private Event currentEvent;
    private Event currentEvent2;
    private String weather;
    private String sqlQuery;
    private String text;
    private Integer i;
    private Integer count = 0;
    private Notification tmrrainy = new Notification();
    private Notification badweather = new Notification();
    private Integer notificationid;
    private UserNotification usernotification = new UserNotification();
    private List<String> Recipients = new ArrayList<String>();
    private List<Event> rainyEvents = new ArrayList<Event>();
    private List<Event> tmrRainyEvents = new ArrayList<Event>();
    private List<Event> badWeatherEvents = new ArrayList<Event>();
    private List<Event> editEvent = new ArrayList<Event>();

    public WeatherBean() {
    }

    public String weatherWithCity(String city) throws IOException {
        String sURL = "http://api.openweathermap.org/data/2.5/weather?q=";
        sURL = sURL + city;

        // Connessione all'url per ricevere lo stream contenente il file json richiesto
        URL url = new URL(sURL);
        HttpURLConnection request = (HttpURLConnection) url.openConnection();
        request.connect();

        // Conversione dello stream di input in un oggetto json
        JsonParser jp = new JsonParser();
        JsonElement root = jp.parse(new InputStreamReader((InputStream) request.getContent()));

        // Ricerca del meteo all'interno dell'oggetto json
        JsonObject rootobj = root.getAsJsonObject();
        weather = rootobj.get("weather").getAsJsonArray().get(0).getAsJsonObject().get("main").getAsString();
        System.out.println("WEATHER BEAN --------> the weather forecast for the city IS: " + weather);

        return weather;

    }

    public static long daysBetween(Calendar startDate, Calendar endDate) {
        long end = endDate.getTimeInMillis();
        long start = startDate.getTimeInMillis();
        return TimeUnit.MILLISECONDS.toDays(Math.abs(end - start));
    }

    public String weatherWithCityDate(String city, String date) throws IOException {

        long diff;

        SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy");
        Calendar cal1 = Calendar.getInstance();
        Calendar cal2 = Calendar.getInstance();
        Date d1 = null;

        try {
            d1 = format.parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }

        cal1.setTime(d1);
        diff = daysBetween(cal2, cal1);
        int intdiff = (int) diff;
        intdiff = intdiff + 1;
        System.out.println("########" + intdiff + "#################");

        if (intdiff <= 15) {
            String sURL = "http://api.openweathermap.org/data/2.5/forecast/daily?q=" + city + "&mode=json&units=metric&cnt=15";

            URL url = new URL(sURL);

            HttpURLConnection request = (HttpURLConnection) url.openConnection();
            request.connect();

            // Conversione dello stream di input in un oggetto json
            JsonParser jp = new JsonParser();
            JsonElement root = jp.parse(new InputStreamReader((InputStream) request.getContent()));

            JsonObject rootobj = root.getAsJsonObject();
            JsonObject rootlist = rootobj.get("list").getAsJsonArray().get(intdiff).getAsJsonObject();
            weather = rootlist.get("weather").getAsJsonArray().get(0).getAsJsonObject().get("main").getAsString();
            //System.out.println("------The weather is: " + weather + "--------------");
            System.out.println("@@@@@@@@@@@@@@@@@@@@@@@@@@@òò ------> " + weather);
            return weather;
        } else {
            return "not available";
        }

    }

    public String firstDayNotRainy(String city) throws IOException, ParseException {
        int i = 0;
        //String city = "London";
        String rain = "Rain";
        String weather = "";

        String sURL = "http://api.openweathermap.org/data/2.5/forecast/daily?q=" + city + "&mode=json&units=metric&cnt=16";
        URL url = new URL(sURL);

        HttpURLConnection request = (HttpURLConnection) url.openConnection();
        request.connect();

        // Conversione dello stream di input in un oggetto json
        JsonParser jp = new JsonParser();
        JsonElement root = jp.parse(new InputStreamReader((InputStream) request.getContent()));
        JsonObject rootobj = root.getAsJsonObject();

        for (i = 3; i < 15; i++) { // i va da 0 a 14 compreso (15 escluso). Più sotto, vedrai che restituisco sempre (i+1) e non direttamente i, così almeno in output la i va da 1 a 16 compresi (è più logico dire il 1° giorno e non lo 0°)

            JsonObject rootlist = rootobj.get("list").getAsJsonArray().get(i).getAsJsonObject();
            weather = rootlist.get("weather").getAsJsonArray().get(0).getAsJsonObject().get("main").getAsString();
            System.out.println("------The weather is: " + weather + " and the day is " + (i) + "--------------");

            if (!weather.equals(rain)) {
                // restituisco i+1 che indica il primo giorno senza pioggia (esempio, se i+1=3, il 3° giorno è il primo senza pioggia)
                //stem.out.println("@@" + i + "@@" + weather + "@@" );
                break;
            }

            
            }

 // Se arrivo qui, quindi se non sono mai entrato nell'if, vuol dire che piove in tutti e 16 i giorni
            // Quindi restituisco 0, come valore speciale che indica appunto che non ci sono giorni in cui non piove
            //System.out.println("------The weather is: " + weather + " and the day is " + (i+1) + "--------------");
            //return 0;
            System.out.println(i);
            Calendar cal1 = Calendar.getInstance();
            cal1.add(Calendar.DAY_OF_YEAR, i);
            System.out.println(cal1.getTime());
            SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy");

            String nextdate = format.format(cal1.getTime());

            System.out.println(nextdate);

            return nextdate;
            //return i;
        }

    

    public void test() {
        System.out.println("------> I'm the Weather Bean and I'm working <------");
    }

    public void checkWeatherNotification() {
        wc.checkTomorrowRainy();
    }

    public void checkTomorrowRainy() {

        rainyEvents = em.getBadEvents();

        tmrRainyEvents = em.getTomorrowRainyEvents();
        Integer count = rainyEvents.size();
        System.out.println("count before iterator IS:" + count + "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
        count = tmrRainyEvents.size();
        System.out.println("count before iterator IS:" + count + "###############################");
        int i;

        if (count != 0) {
            System.out.println("-------------I'M IN THE FIRST IF-------------");
            for (i = 0; i < count; i++) {
                System.out.println("-----I'M IN THE FIRST FOR NUMBER" + i + "--------");
                Event currentEvent = tmrRainyEvents.get(i);
                Recipients = nm.getRecipients2(currentEvent.getId());
                Integer countt = Recipients.size();
                System.out.println("count of recipient IS:" + countt + "***********************");

                if (countt != 0) {
                    System.out.println("-------------I'M IN THE SECOND IF-------------");
                    text = "The outdoor event " + currentEvent.getEventname()
                            + " scheduled for tomorrow will have RAINY weather!";
                    this.tmrrainy.setText(text);
                    this.tmrrainy.setEventid(currentEvent.getId());
                    this.tmrrainy.setType("tomorrowRainy");
                    System.out.println(tmrrainy.getEventid());
                    System.out.println(tmrrainy.getText());
                    System.out.println(tmrrainy.getType());

                    nm.saveNotification(this.tmrrainy);

                    notificationid = tmrrainy.getId();
                    System.out.println(tmrrainy.getId());

                    usernotification.setNotificationid(notificationid);
                    int j;
                    for (j = 0; j < countt; j++) {
                        System.out.println("-----I'M IN THE SECONDO FOR NUMBER" + j + "--------");
                        String currentRecipient = Recipients.get(j);
                        usernotification.setUsermail(currentRecipient);
                        System.out.println(usernotification.getUsermail());
                        System.out.println(usernotification.getNotificationid());
                        unm.saveUserNotification(usernotification);
                    }
                }
            }
        }

        //return "startpage";
    }

    public void checkBadWeather() throws IOException, ParseException {

        rainyEvents = em.getBadEvents();

        badWeatherEvents = em.getBadWeatherEvents();
        Integer count = rainyEvents.size();
        System.out.println("count before iterator IS:" + count + "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
        count = badWeatherEvents.size();
        System.out.println("count before iterator IS:" + count + "###############################");
        int i;

        if (count != 0) {
            System.out.println("-------------I'M IN THE FIRST IF-------------");
            for (i = 0; i < count; i++) {
                System.out.println("-----I'M IN THE FIRST FOR NUMBER" + i + "--------");
                Event currentEvent = badWeatherEvents.get(i);
                Recipients = nm.getRecipients3(currentEvent.getId());
                Integer countt = Recipients.size();
                System.out.println("count of recipient IS:" + countt + "***********************");

                if (countt != 0) {
                    System.out.println("-------------I'M IN THE SECOND IF-------------");
                    String nextdate = firstDayNotRainy(currentEvent.getCity());
                   
                    text = "The outdoor event " + currentEvent.getEventname()
                            + " scheduled in 3 days will have RAINY weather!"
                            + " Do you want to change to date to " + nextdate + " ?";
                    this.badweather.setText(text);
                    this.badweather.setEventid(currentEvent.getId());
                    this.badweather.setType("badWeather");
                    System.out.println(badweather.getEventid());
                    System.out.println(badweather.getText());
                    System.out.println(badweather.getType());

                    if (nm == null) {
                        System.out.println("IS NULL @@@");
                    }
                    nm.saveNotification(this.badweather);

                    notificationid = badweather.getId();
                    System.out.println(badweather.getId());

                    usernotification.setNotificationid(notificationid);
                    int j;
                    for (j = 0; j < countt; j++) {
                        System.out.println("-----I'M IN THE SECONDO FOR NUMBER" + j + "--------");
                        String currentRecipient = Recipients.get(j);
                        usernotification.setUsermail(currentRecipient);
                        System.out.println(usernotification.getUsermail());
                        System.out.println(usernotification.getNotificationid());
                        unm.saveUserNotification(usernotification);
                    }
                }
            }
        }

        //return "startpage";
    }

    public String AcceptSuggestion(Integer notid) throws IOException, ParseException {
        System.out.println("The ID of the usernotification IS " + notid);
        editEvent = em.getEvents2(notid);
        Integer count = editEvent.size();
        System.out.println("The event to update must be only one--> " + count);
        int i;
        for (i = 0; i < count; i++) {
            currentEvent2 = editEvent.get(i);
            System.out.println("START ------ EVENT TO UPDATE INFORMATION --------");
            System.out.println(currentEvent2.getEventname());
            System.out.println(currentEvent2.getCity());
            System.out.println(currentEvent2.getEventdate());
            System.out.println(currentEvent2.getWeather());
            System.out.println("END ------ EVENT TO UPDATE INFORMATION --------");

            String nextdate = firstDayNotRainy(currentEvent2.getCity());
            System.out.println("The new date is --> " + nextdate);
            currentEvent2.setEventdate(nextdate);
            String neweather = weatherWithCityDate(currentEvent2.getCity(), nextdate);
            currentEvent2.setWeather(neweather);
            System.out.println("The new weather is --> " + neweather);
            em.updateEvent(currentEvent2);

            Integer unid = nm.findUserNotification(notid);
            usernotification.setId(unid);
            usernotification.setNotificationid(notid);
            String LogUser = um.getLoggedUser().getEmail();
            usernotification.setUsermail(LogUser);

            unm.deleteUserNotification(usernotification);

        }

        return "/user/badWeather/showConfirm2";
    }

}
